package com.soa.zuul.filter;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.soa.zuul.entity.GatewayHttpApi;
import com.soa.zuul.entity.GatewayUser;
import com.soa.zuul.service.FeignLogService;
import com.soa.zuul.util.CodeMsg;
import com.soa.zuul.util.Constant;
import com.soa.zuul.util.IpWhiteCheckUtil;
import com.soa.zuul.util.Json;
import com.soa.zuul.util.RequestUtil;

/**
 * APP白名单过滤
 * @author zheng
 *
 */
public class WhiteBlackListFilter extends ZuulFilter {
	public final static Logger logger = LoggerFactory.getLogger(WhiteBlackListFilter.class);
	FeignLogService feignLogService;
	public WhiteBlackListFilter(FeignLogService feignLogService) {
		this.feignLogService =feignLogService;
	}

	/**
	 * 过滤器的具体逻辑
	 *
	 * 通过ctx.setSendZuulResponse(false)令zuul过滤该请求，不对其进行路由，
	 * 通过ctx.setResponseStatusCode(401)设置了其返回的错误码
	 * 通过ctx.setResponseBody(body)对返回body内容进行编辑等。
	 * 中文乱码：ctx.getResponse().setContentType("text/html;charset=UTF-8");
	 * 
	 * @return
	 */
	@Override
	public Object run() {
		 CodeMsg codeMsg = CodeMsg.SUCCESS;
		 RequestContext ctx = RequestContext.getCurrentContext();
		 GatewayHttpApi gatewayHttpApi=(GatewayHttpApi)ctx.get("gatewayHttpApi");
		 GatewayUser gatewayUser=(GatewayUser)ctx.get("gatewayUser");
		 String ip = (String)ctx.get("ip");
		 //基于用户的IP白名单
		 if(gatewayUser!=null){
			if(!StringUtils.isEmpty(gatewayUser.getIsOpenWhiteList()) && Constant.whiteListIsYes.equals(gatewayUser.getIsOpenWhiteList()) && !IpWhiteCheckUtil.isPermited(ip, gatewayUser.getWhiteList())){
				codeMsg = CodeMsg.USER_IP_ERROR;
				feignLogService.writeLog(Json.GSON.toJson(RequestUtil.SendZuulResponseError(codeMsg, ctx))) ;
				return null;
			}
		 }
		 //基于app的白名单
		 if(!StringUtils.isEmpty(gatewayHttpApi) && !StringUtils.isEmpty(gatewayHttpApi.getIsOpenWhiteList()) && Constant.whiteListIsYes.equals(gatewayHttpApi.getIsOpenWhiteList()) && !IpWhiteCheckUtil.isPermited(ip, gatewayHttpApi.getWhiteList())){
				codeMsg = CodeMsg.APP_IP_ERROR;
				feignLogService.writeLog(Json.GSON.toJson(RequestUtil.SendZuulResponseError(codeMsg, ctx))) ;
				return null;
		 }
		 
		 //黑名单用户预留
		 
		return null;
	}

	/**
	 * 返回一个boolean类型来判断该过滤器是否要执行，返回true，则过滤器生效
	 * 
	 * @return
	 */
	@Override
	public boolean shouldFilter() {
		 RequestContext ctx = RequestContext.getCurrentContext();
		 if(ctx.get("isSuccess")==null) return false;
		 return (boolean) ctx.get("isSuccess");//
	}


	@Override
	public int filterOrder() {
		return 40; // 过滤器的优先级
	}

	/**
	 * 返回一个字符串代表过滤器的类型，在zuul中定义了四种不同生命周期的过滤器类型，具体如下： pre：可以在请求被路由之前调用
	 * routing：在路由请求时候被调用 post：在routing和error过滤器之后被调用 error：处理请求时发生错误时被调用
	 * 
	 * @return
	 */
	@Override
	public String filterType() {
		return "pre";
	}

}
